package com.bigluo.common.interceptor;


import com.alibaba.fastjson.JSON;
import com.bigluo.api.BaseResponse;
import com.bigluo.util.CustomHttpMessageConverter;
import com.bigluo.util.md5.MD5Util;
import com.bigluo.util.md5.MapUtils;
import org.apache.log4j.MDC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by luojun on 2017/9/1.
 * spring mvc通用拦截器 拦截spring mvc所有的请求
 * 主要用来统一加签验签操作
 */
public class CommonInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private ServletContext servletContext;
    private Logger logger = LoggerFactory.getLogger(CommonInterceptor.class);
    private String secretKey;
    private String md5Switch;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        MDC.put("requestId", UUID.randomUUID().toString().replace("-",""));
        String requestUri = request.getRequestURI();
        logger.info("http调接口方法：{},入参为：{}", requestUri,JSON.toJSONString(request.getParameterMap()));
        if(handler instanceof DefaultServletHttpRequestHandler) {//静态资源请求直接返回 不处理
            return true;
        }
        BaseResponse baseResponse = validateInputParam(request);
        if(baseResponse!=null) {
            //获取spring mvc容器中的bean
            WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext, "org.springframework.web.servlet.FrameworkServlet.CONTEXT.springmvc");
            CustomHttpMessageConverter customHttpMessageConverter = webApplicationContext.getBean(CustomHttpMessageConverter.class);
            customHttpMessageConverter.write(baseResponse, MediaType.ALL,new ServletServerHttpResponse(response));
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //logger.info("6 springmvc interceptor posthandler 处理开始");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //logger.info("7 springmvc interceptor afterCompletion 处理开始");
    }

    private BaseResponse validateInputParam(HttpServletRequest request) throws Exception{
        if("true".equals(md5Switch)) {
            Map paramMap = request.getParameterMap();
            String sign = request.getParameter("sign");
            Map<String,String>priorMap = new HashMap<String, String>();
            for(Object obj:paramMap.keySet()) {
                String ss = (String)obj;
                priorMap.put(ss,request.getParameter(ss));
            }
            priorMap.remove("sign");
            priorMap = MapUtils.removeNull(priorMap);
            String mingwen = MapUtils.sortStringByLine(priorMap);
            logger.info("MD5待加签明文：{}",mingwen+secretKey);
            String miwen = MD5Util.getMD5String(mingwen+secretKey,"utf-8");
            if(!miwen.equals(sign)) {
                logger.info("验签失败,上游密文：{},本地密文：{}",sign,miwen);
                BaseResponse rsp = new BaseResponse();
                rsp.setRspCode("T22222");
                rsp.setRspMsg("验签失败");
                return rsp;
            }
        }
        return null;

    }

    public Logger getLogger() {
        return logger;
    }

    public void setLogger(Logger logger) {
        this.logger = logger;
    }

    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    public String getMd5Switch() {
        return md5Switch;
    }

    public void setMd5Switch(String md5Switch) {
        this.md5Switch = md5Switch;
    }
}
